package cn.zhfeat.utils;

import org.apache.poi.xssf.usermodel.*;

import javax.servlet.http.HttpServletResponse;

import java.io.BufferedOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 
 * @Title ExportExcel.java
 * @Description 导出excel
 * @author wschenyongyin
 * @date 2017年9月18日
 * @version 1.0
 */

public class ExportExcel<T> {

	/**
	 * 
	 * Title: exportExcel Description:
	 * 
	 * @param headers
	 *            列表 标题
	 * @param dataset
	 *            数据
	 * @param fileName
	 *            表名称
	 * @param response
	 */

	public int exportExcel(String[] headers, Collection<T> dataset, String fileName, HttpServletResponse response,
			String... excludeFields) {
		// 声明一个工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		// 生成一个表格
		XSSFSheet sheet = workbook.createSheet(fileName);
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth((short) 20);
		// 产生表格标题行
		XSSFRow row = sheet.createRow(0);
		for (short i = 0; i < headers.length; i++) {
			XSSFCell cell = row.createCell(i);
			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}
		try {
			// 遍历集合数据，产生数据行
			Iterator<T> it = dataset.iterator();
			int index = 0;
			while (it.hasNext()) {
				index++;
				row = sheet.createRow(index);
				T t = (T) it.next();
				// 利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
				Field[] fields = t.getClass().getDeclaredFields();
				int cellIndex=0;
				int fieldIndex=0;
				for (short i = 0; i < headers.length; i++) {
					Field field = fields[fieldIndex];
					String fieldName = field.getName();
					fieldIndex++;
					// 过滤字段
					if (excludeFields != null && excludeFields.length > 0) {
						if (hasFieId(fieldName, excludeFields)) {
							i--;
							continue;
						}
					}
					XSSFCell cell = row.createCell(cellIndex);
					String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					Class tCls = t.getClass();
					Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
					Object value = getMethod.invoke(t, new Object[] {});
					// 判断值的类型后进行强制类型转换
					String textValue = null;
					// 其它数据类型都当作字符串简单处理
					if (value != null && value != "") {
						textValue = value.toString();
					}
					if (textValue != null) {
						XSSFRichTextString richString = new XSSFRichTextString(textValue);
						cell.setCellValue(richString);
					}
					cellIndex++;
				}
			}
			return getExportedFile(workbook, fileName, response);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	public int exportExcel(String[] headers, List<Map<String,Object>> datas,
			String fileName, HttpServletResponse response) {
		// 声明一个工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		// 生成一个表格
		XSSFSheet sheet = workbook.createSheet(fileName);
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth((short) 20);
		// 产生表格标题行
		XSSFRow row = sheet.createRow(0);
		for (short i = 0; i < headers.length; i++) {
			XSSFCell cell = row.createCell(i);
			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}
		try {
			
			for(Map<String,Object> map:datas){
				int i=0;
				for (Object value : map.values()) {
					XSSFCell cell = row.createCell(i);
					// 判断值的类型后进行强制类型转换
					String textValue = null;
					// 其它数据类型都当作字符串简单处理
					if (value != null && value != "") {
						textValue = value.toString();
					}
					if (textValue != null) {
						XSSFRichTextString richString = new XSSFRichTextString(
								textValue);
						cell.setCellValue(richString);
					}
					i++;
				}
			}
			return getExportedFile(workbook, fileName, response);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * 
	 * 方法说明: 指定路径下生成EXCEL文件
	 * 
	 * @return
	 */
	public int getExportedFile(XSSFWorkbook workbook, String name,
			HttpServletResponse response) throws Exception {
		BufferedOutputStream fos = null;
		try {
			String fileName = name + ".xlsx";
			System.out.println("fileNmae-->" + fileName);
			response.setHeader("Content-Disposition", "attachment;filename="
					+ new String(fileName.getBytes("gb2312"), "ISO8859-1"));
			// response.addHeader("Content-Disposition", "attachment;filename="+
			// new String(fileName.getBytes()));
			response.setContentType("application/x-msdownload");

			fos = new BufferedOutputStream(response.getOutputStream());
			workbook.write(fos);
			return 1;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
	}
	
	
	/*
	*//**
	 * 
	 * Title: exportExcel Description:
	 * 生成两个工作簿(会员数据导入使用)
	 * @param headers
	 *            列表 标题
	 * @param dataset
	 *            数据
	 * @param fileName
	 *            表名称
	 * @param response
	 *//*

	public int exportExcelTwoSheet(String[] headers,String[] headers2,Collection<exportManageErrorBean> dataset,Collection<exportManageStoreBean> dataset2,String fileName,String fileName2,String templateName,HttpServletResponse response) {
		// 声明一个工作薄
		XSSFWorkbook workbook = new XSSFWorkbook();
		// 生成一个表格
		XSSFSheet sheet = workbook.createSheet(fileName);
		// 生成第二个表格
		XSSFSheet sheet2 = workbook.createSheet(fileName2);
		// 设置表格默认列宽度为15个字节
		sheet.setDefaultColumnWidth((short) 20);
		
		// 产生表格标题行
		XSSFRow row = sheet.createRow(0);
		for (short i = 0; i < headers.length; i++) {
			XSSFCell cell = row.createCell(i);
			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
			cell.setCellValue(text);
		}
		try {
			// 遍历集合数据，产生数据行
			Iterator<T> it = (Iterator<T>) dataset.iterator();
			int index = 0;
			while (it.hasNext()) {
				index++;
				row = sheet.createRow(index);
				T t = (T) it.next();
				// 利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
				Field[] fields = t.getClass().getDeclaredFields();
				for (short i = 0; i < headers.length; i++) {
					XSSFCell cell = row.createCell(i);
					Field field = fields[i];
					String fieldName = field.getName();
					System.out.println(field);
					String getMethodName = "get"
							+ fieldName.substring(0, 1).toUpperCase()
							+ fieldName.substring(1);
					Class tCls = t.getClass();
					Method getMethod = tCls.getMethod(getMethodName,
							new Class[] {});
					Object value = getMethod.invoke(t, new Object[] {});
					// 判断值的类型后进行强制类型转换
					String textValue = null;
					// 其它数据类型都当作字符串简单处理
					if (value != null && value != "") {
						textValue = value.toString();
					}
					if (textValue != null) {
						XSSFRichTextString richString = new XSSFRichTextString(
								textValue);
						cell.setCellValue(richString);
					}
				}
			}
			
			
			// 产生表格标题行
			XSSFRow row2 = sheet2.createRow(0);
			for (short i = 0; i < headers2.length; i++) {
				XSSFCell cell = row2.createCell(i);
				XSSFRichTextString text = new XSSFRichTextString(headers2[i]);
				cell.setCellValue(text);
			}
			
				// 遍历集合数据，产生数据行
				Iterator<T> it2 = (Iterator<T>) dataset2.iterator();
				int index2 = 0;
				while (it2.hasNext()) {
					index2++;
					row2 = sheet2.createRow(index2);
					T t = (T) it2.next();
					// 利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
					Field[] fields = t.getClass().getDeclaredFields();
					for (short i = 0; i < headers2.length; i++) {
						XSSFCell cell = row2.createCell(i);
						Field field = fields[i];
						String fieldName = field.getName();
						System.out.println(field);
						String getMethodName = "get"
								+ fieldName.substring(0, 1).toUpperCase()
								+ fieldName.substring(1);
						Class tCls = t.getClass();
						Method getMethod = tCls.getMethod(getMethodName,
								new Class[] {});
						Object value = getMethod.invoke(t, new Object[] {});
						// 判断值的类型后进行强制类型转换
						String textValue = null;
						// 其它数据类型都当作字符串简单处理
						if (value != null && value != "") {
							textValue = value.toString();
						}
						if (textValue != null) {
							XSSFRichTextString richString = new XSSFRichTextString(
									textValue);
							cell.setCellValue(richString);
						}
					}
				}
			
			return getExportedFile(workbook, templateName, response);
			
			
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
			
	}*/
	private Boolean hasFieId(String fieId, String[] fieIds) {
		boolean result = false;
		for (String excludeFieId : fieIds) {
			if (fieId.equals(excludeFieId)) {
				result = true;
				break;
			}
		}
		return result;
	}
}
